<template>
  <Transition
      :name="transitionName"
      @after-leave="destroyComponent"
      @enter="updateHeight"
  >
    <div
        class="vk-message"
        role="alert"
        v-show="visible"
        :class="{
        [`vk-message--${type}`]:type,
        'is-close':showClose
      }"
        ref="messageRef"
        :style="cssStyle"
        @mouseenter="clearTimer"
        @mouseleave="startTimer"
    >
      <div class="vk-message__content">
        <slot>
          {{ offset }}-{{ topOffset }}-{{ height }}-{{ bottomOffset }}-{{ lastOffset }}
          <RenderVnode :vNode="message" v-if="message"/>
        </slot>
      </div>
      <div class="vk-message__close" v-if="showClose">
        <icon icon="xmark" @click.stop="visible=false"/>
      </div>
    </div>
  </Transition>
</template>
<script setup lang="ts">
import type {MessageProps} from "./types";
import Icon from "@/App.vue";
import {computed, nextTick, onMounted, ref, watch} from "vue";
import {getLastBottomOffset} from "@/components/Message/method";
import RenderVnode from "@/components/common/RenderVnode";
import useEventListener from '@/hook/useEventListener'

const props = withDefaults(defineProps<MessageProps>(), {
  type: 'info',
  duration: 3000,
  offset: 20
})
const visible = ref(false)
const messageRef = ref<HTMLDivElement>()

// 计算便宜高度
// 这个div的高度
const height = ref(0)
// 上一个实例的最下面的坐标数字，第一个是0
const lastOffset = computed(() => getLastBottomOffset(props.id!))
// 这个元素应该使用的 top
const topOffset = computed(() => props.offset + lastOffset.value)
// 这个元素为下一个元素预留的offset,也就是它最低端的bottom的值
const bottomOffset = computed(() => height.value + topOffset.value)
const cssStyle = computed(() => ({
  top: topOffset.value + 'px'
}))

let timer: any

function startTimer() {
  if (props.duration === 0) return
  timer = setTimeout(() => {
    visible.value = false
  }, props.duration)
}

function clearTimer() {
  clearTimeout(timer)
}


function keydown(e: Event) {
  const event = e as KeyboardEvent
  if (event.code === 'Escape') {
    visible.value = false
  }
}

useEventListener(document, 'keydown', keydown)

onMounted(async () => {
  visible.value = true
  startTimer()
  // await nextTick()
  // height.value = messageRef.value!.getBoundingClientRect().height
})

function updateHeight() {
  height.value = messageRef.value!.getBoundingClientRect().height
}
function destroyComponent () {
  props.onDestroy()
}

// watch(visible, (newValue) => {
//   if (!newValue) {
//     props.onDestroy();
//   }
// })
function keydowm(e: Event) {
  const event = e as KeyboardEvent
  if (event.code === 'Escape') {
    visible.value = false
  }
}

defineExpose({
  bottomOffset,
  visible
})
</script>
